﻿
namespace NComputerVision.Test
{
    using System.Diagnostics;
    using System.Drawing;
    using System.IO;
    using log4net;
    using Microsoft.VisualStudio.TestTools.UnitTesting;
    using NComputerVision.Common;
    using NComputerVision.DataStructures;
    using NComputerVision.Image;

    [TestClass()]
    public class ComputerVision
    {
        private const string Data_Folder = @"..\data";
        private Stopwatch stopwatch = new Stopwatch();
        private static readonly ILog log = LogManager.GetLogger(typeof(ComputerVision));

        #region Additional test attributes
        // 
        //You can use the following additional attributes as you write your tests:
        //
        //Use ClassInitialize to run code before running the first test in the class
        //[ClassInitialize()]
        //public static void MyClassInitialize(TestContext testContext)
        //{
        //}
        //
        //Use ClassCleanup to run code after all tests in a class have run
        //[ClassCleanup()]
        //public static void MyClassCleanup()
        //{
        //}
        //
        //Use TestInitialize to run code before running each test
        //[TestInitialize()]
        //public void MyTestInitialize()
        //{
        //}
        //
        //Use TestCleanup to run code after each test has run
        //[TestCleanup()]
        //public void MyTestCleanup()
        //{
        //}
        //
        #endregion

        [TestMethod()]
        public void GaussianTest()
        {
            string fileName = Path.Combine(Data_Folder, "lena_color.tiff");
            Bitmap bmp = new Bitmap(fileName);
            Bitmap newBmp;

            stopwatch.Reset();
            stopwatch.Start();
            newBmp = GrayScaleProcessor.Gaussian(bmp, 1.4);
            stopwatch.Stop();
            //Assert.Less(stopwatch.ElapsedMilliseconds, 400);
            log.Info("Gaussian spent {0} ms.", stopwatch.ElapsedMilliseconds);

            stopwatch.Reset();
            stopwatch.Start();
            newBmp = RgbProcessor.Gaussian(bmp, 1.4);
            stopwatch.Stop();
            //Assert.Less(stopwatch.ElapsedMilliseconds, 468);
            log.Info("GaussianColor spent {0} ms.", stopwatch.ElapsedMilliseconds);

        }

        [TestMethod()]
        public void MedianTest()
        {
            string fileName = Path.Combine(Data_Folder, "lena_color.tiff");
            Bitmap bmp = new Bitmap(fileName);
            Bitmap newBmp;

            stopwatch.Reset();
            stopwatch.Start();
            newBmp = RgbProcessor.Median(bmp, 5);
            stopwatch.Stop();
            //Assert.Less(stopwatch.ElapsedMilliseconds, 700);
            log.Info("GaussianColor spent {0} ms.", stopwatch.ElapsedMilliseconds);

        }

        [TestMethod()]
        public void KMeanTest()
        {
            string fileName = Path.Combine(Data_Folder, "lena_color.tiff");
            Bitmap bmp = new Bitmap(fileName);
            Bitmap newBmp;

            stopwatch.Reset();
            stopwatch.Start();
            newBmp = GrayScaleProcessor.K_Mean(bmp, 9);
            stopwatch.Stop();
            //Assert.Less(stopwatch.ElapsedMilliseconds, 300);
            log.Info("K_Mean spent {0} ms.", stopwatch.ElapsedMilliseconds);

            stopwatch.Reset();
            stopwatch.Start();
            newBmp = RgbProcessor.K_Mean(bmp, 9);
            stopwatch.Stop();
            //Assert.Less(stopwatch.ElapsedMilliseconds, 400);
            log.Info("K_MeanColor spent {0} ms.", stopwatch.ElapsedMilliseconds);
        }

        [TestMethod()]
        public void GrayScaleTest()
        {
            string fileName = Path.Combine(Data_Folder, "lena_color.tiff");
            Bitmap bmp = new Bitmap(fileName);
            Bitmap newBmp;

            stopwatch.Reset();
            stopwatch.Start();
            newBmp = GrayScaleProcessor.GrayScale(bmp);
            stopwatch.Stop();
            //Assert.Less(stopwatch.ElapsedMilliseconds, 15);
            log.Info("GrayScale spent {0} ms.", stopwatch.ElapsedMilliseconds);
        }

        [TestMethod()]
        public void NormalizeTest()
        {
            string fileName = Path.Combine(Data_Folder, "lena_color.tiff");
            Bitmap bmp = new Bitmap(fileName);
            Bitmap newBmp;
            
            stopwatch.Reset();
            stopwatch.Start();
            newBmp = GrayScaleProcessor.Normalize(bmp);
            stopwatch.Stop();
            //Assert.Less(stopwatch.ElapsedMilliseconds, 16);
            log.Info("Normalize spent {0} ms.", stopwatch.ElapsedMilliseconds);
        }

        [TestMethod()]
        public void RobustNormalizeTest()
        {
            string fileName = Path.Combine(Data_Folder, "lena_color.tiff");
            Bitmap bmp = new Bitmap(fileName);
            Bitmap newBmp;
            
            stopwatch.Reset();
            stopwatch.Start();
            newBmp = GrayScaleProcessor.RobustNormalize(bmp, 0.01, 0.99);
            stopwatch.Stop();
            //Assert.Less(stopwatch.ElapsedMilliseconds, 32);
            log.Info("Robust Normalize spent {0} ms.", stopwatch.ElapsedMilliseconds);
        }

        [TestMethod()]
        public void PrewittTest()
        {
            string fileName = Path.Combine(Data_Folder, "lena_color.tiff");
            Bitmap bmp = new Bitmap(fileName);
            Bitmap newBmp;
            
            stopwatch.Reset();
            stopwatch.Start();
            newBmp = GrayScaleProcessor.Prewitt(bmp);
            stopwatch.Stop();
            //Assert.Less(stopwatch.ElapsedMilliseconds, 320);
            log.Info("Prewitt spent {0} ms.", stopwatch.ElapsedMilliseconds);
        }

        [TestMethod()]
        public void SobelTest()
        {
            string fileName = Path.Combine(Data_Folder, "lena_color.tiff");
            Bitmap bmp = new Bitmap(fileName);
            Bitmap newBmp;
            
            stopwatch.Reset();
            stopwatch.Start();
            newBmp = GrayScaleProcessor.Sobel(bmp);
            stopwatch.Stop();
            //Assert.Less(stopwatch.ElapsedMilliseconds, 330);
            log.Info("Sobel spent {0} ms.", stopwatch.ElapsedMilliseconds);
        }

        [TestMethod()]
        public void ConnectedComponentsTest()
        {
            string fileName = Path.Combine(Data_Folder, "connected.tif");
            Bitmap bmp = new Bitmap(fileName);
            Bitmap newBmp;
            
            ConnectedComponents cc = new ConnectedComponents(bmp);

            stopwatch.Reset();
            stopwatch.Start();
            newBmp = cc.Caculate();
            stopwatch.Stop();
            //Assert.Less(stopwatch.ElapsedMilliseconds, 16);
            log.Info("ConnectedComponents spent {0} ms.", stopwatch.ElapsedMilliseconds);
        }

        [TestMethod()]
        public void AffineTransformationTest()
        {
            string fileName = Path.Combine(Data_Folder, "lena_color.tiff");
            Bitmap bmp = new Bitmap(fileName);
            Bitmap newBmp;     

            stopwatch.Reset();
            stopwatch.Start();
            newBmp = GrayScaleAffineTransformation.Translate(bmp, 50, 50);
            stopwatch.Stop();
            //Assert.Less(stopwatch.ElapsedMilliseconds, 300);
            log.Info("Translate spent {0} ms.", stopwatch.ElapsedMilliseconds);

            stopwatch.Reset();
            stopwatch.Start();
            newBmp = GrayScaleAffineTransformation.Scale(bmp, 0.5, 0.5);
            stopwatch.Stop();
            //Assert.Less(stopwatch.ElapsedMilliseconds, 300);
            log.Info("Scale spent {0} ms.", stopwatch.ElapsedMilliseconds);

            stopwatch.Reset();
            stopwatch.Start();
            newBmp = GrayScaleAffineTransformation.Rotate(bmp, 0.5, true);
            stopwatch.Stop();
            //Assert.Less(stopwatch.ElapsedMilliseconds, 300);
            log.Info("Rotate spent {0} ms.", stopwatch.ElapsedMilliseconds);

            stopwatch.Reset();
            stopwatch.Start();
            newBmp = GrayScaleAffineTransformation.Skew(bmp, 0.5, true);
            stopwatch.Stop();
            //Assert.Less(stopwatch.ElapsedMilliseconds, 300);
            log.Info("Skew spent {0} ms.", stopwatch.ElapsedMilliseconds);
        }

        [TestMethod()]
        public void AffineTransformationColorTest()
        {
            string fileName = Path.Combine(Data_Folder, "lena_color.tiff");
            Bitmap bmp = new Bitmap(fileName);
            Bitmap newBmp;        

            stopwatch.Reset();
            stopwatch.Start();
            newBmp = RgbAffineTransformation.Translate(bmp, 50, 50);
            stopwatch.Stop();
            //Assert.Less(stopwatch.ElapsedMilliseconds, 300);
            log.Info("Translate spent {0} ms.", stopwatch.ElapsedMilliseconds);

            stopwatch.Reset();
            stopwatch.Start();
            newBmp = RgbAffineTransformation.Scale(bmp, 0.5, 0.5);
            stopwatch.Stop();
            //Assert.Less(stopwatch.ElapsedMilliseconds, 300);
            log.Info("Scale spent {0} ms.", stopwatch.ElapsedMilliseconds);

            stopwatch.Reset();
            stopwatch.Start();
            newBmp = RgbAffineTransformation.Rotate(bmp, 0.5, true);
            stopwatch.Stop();
            //Assert.Less(stopwatch.ElapsedMilliseconds, 300);
            log.Info("Rotate spent {0} ms.", stopwatch.ElapsedMilliseconds);

            stopwatch.Reset();
            stopwatch.Start();
            newBmp = RgbAffineTransformation.Skew(bmp, 0.5, true);
            stopwatch.Stop();
            //Assert.Less(stopwatch.ElapsedMilliseconds, 300);
            log.Info("Skew spent {0} ms.", stopwatch.ElapsedMilliseconds);            
        }

        [TestMethod()]
        public void SharpenEdgesTest()
        {
            string fileName = Path.Combine(Data_Folder, "lena_color.tiff");
            Bitmap bmp = new Bitmap(fileName);
            Bitmap newBmp;
            
            ConnectedComponents cc = new ConnectedComponents(bmp);

            stopwatch.Reset();
            stopwatch.Start();
            newBmp = RgbProcessor.SharpenEdges(bmp);
            stopwatch.Stop();
            //Assert.Less(stopwatch.ElapsedMilliseconds, 700);
            log.Info("SharpenEdges spent {0} ms.", stopwatch.ElapsedMilliseconds);
        }

        [TestMethod()]
        public void SkeletonExtractionTest()
        {
            string fileName = Path.Combine(Data_Folder, "connected.tif");
            Bitmap bmp = new Bitmap(fileName);
            Bitmap newBmp;
            
            stopwatch.Reset();
            stopwatch.Start();
            newBmp = GrayScaleProcessor.ExtractSkeleton(bmp);
            stopwatch.Stop();
            //Assert.Less(stopwatch.ElapsedMilliseconds, 1000);
            log.Info("SkeletonExtraction spent {0} ms.", stopwatch.ElapsedMilliseconds);
        }

        [TestMethod()]
        public void GrayValueDilationTest()
        {
            string fileName = Path.Combine(Data_Folder, "lena_color.tiff");
            Bitmap bmp = new Bitmap(fileName);
            Bitmap newBmp;
            
            stopwatch.Reset();
            stopwatch.Start();
            newBmp = GrayScaleProcessor.GrayValueDilation(bmp);
            stopwatch.Stop();
            //Assert.Less(stopwatch.ElapsedMilliseconds, 300);
            log.Info("GrayValueDilation spent {0} ms.", stopwatch.ElapsedMilliseconds);
        }

        [TestMethod()]
        public void GrayValueErosionTest()
        {
            string fileName = Path.Combine(Data_Folder, "lena_color.tiff");
            Bitmap bmp = new Bitmap(fileName);
            Bitmap newBmp;
            
            stopwatch.Reset();
            stopwatch.Start();
            newBmp = GrayScaleProcessor.GrayValueErosion(bmp);
            stopwatch.Stop();
            //Assert.Less(stopwatch.ElapsedMilliseconds, 300);
            log.Info("GrayValueErosion spent {0} ms.", stopwatch.ElapsedMilliseconds);
        }

        [TestMethod()]
        public void GrayValueInverseTest()
        {
            string fileName = Path.Combine(Data_Folder, "lena_color.tiff");
            Bitmap bmp = new Bitmap(fileName);
            Bitmap newBmp;            

            stopwatch.Reset();
            stopwatch.Start();
            newBmp = GrayScaleProcessor.GrayValueInverse(bmp);
            stopwatch.Stop();
            //Assert.Less(stopwatch.ElapsedMilliseconds, 300);
            log.Info("GrayValueInverse spent {0} ms.", stopwatch.ElapsedMilliseconds);
        }

        [TestMethod()]
        public void GrayValueOpenTest()
        {
            string fileName = Path.Combine(Data_Folder, "lena_color.tiff");
            Bitmap bmp = new Bitmap(fileName);
            Bitmap newBmp;
            
            stopwatch.Reset();
            stopwatch.Start();
            newBmp = GrayScaleProcessor.GrayValueOpen(bmp);
            stopwatch.Stop();
            //Assert.Less(stopwatch.ElapsedMilliseconds, 300);
            log.Info("GrayValueOpen spent {0} ms.", stopwatch.ElapsedMilliseconds);
        }

        [TestMethod()]
        public void GrayValueCloseTest()
        {
            string fileName = Path.Combine(Data_Folder, "lena_color.tiff");
            Bitmap bmp = new Bitmap(fileName);
            Bitmap newBmp;            

            stopwatch.Reset();
            stopwatch.Start();
            newBmp = GrayScaleProcessor.GrayValueClose(bmp);
            stopwatch.Stop();
            //Assert.Less(stopwatch.ElapsedMilliseconds, 300);
            log.Info("GrayValueClose spent {0} ms.", stopwatch.ElapsedMilliseconds);
        }

        [TestMethod()]
        public void IntegralImageTest()
        {
            int[][] mat = Util.BuildMatInt(4, 4);
            mat[0][0] = 1; mat[0][1] = 1; mat[0][2] = 1; mat[0][3] = 1;
            mat[1][0] = 1; mat[1][1] = 1; mat[1][2] = 1; mat[1][3] = 1;
            mat[2][0] = 1; mat[2][1] = 1; mat[2][2] = 1; mat[2][3] = 1;
            mat[3][0] = 1; mat[3][1] = 1; mat[3][2] = 1; mat[3][3] = 1;
            IntegralImage iImage = new IntegralImage(mat);

            Assert.AreEqual(1, iImage.GetValue(0, 0));
            Assert.AreEqual(2, iImage.GetValue(0, 1));
            Assert.AreEqual(3, iImage.GetValue(0, 2));
            Assert.AreEqual(4, iImage.GetValue(0, 3));
            Assert.AreEqual(2, iImage.GetValue(1, 0));
            Assert.AreEqual(4, iImage.GetValue(1, 1));
            Assert.AreEqual(6, iImage.GetValue(1, 2));
            Assert.AreEqual(8, iImage.GetValue(1, 3));
            Assert.AreEqual(3, iImage.GetValue(2, 0));
            Assert.AreEqual(6, iImage.GetValue(2, 1));
            Assert.AreEqual(9, iImage.GetValue(2, 2));
            Assert.AreEqual(12, iImage.GetValue(2, 3));
            Assert.AreEqual(4, iImage.GetValue(3, 0));
            Assert.AreEqual(8, iImage.GetValue(3, 1));
            Assert.AreEqual(12, iImage.GetValue(3, 2));
            Assert.AreEqual(16, iImage.GetValue(3, 3));

        }

       
    }
}
